package main

import (
	"fmt"
	"log"
	"time"
)

// DemoCBR demonstrates CBR protocol usage
func DemoCBR() {
	fmt.Println("=== CBR Protocol Demo ===")
	
	// Create logger
	logger := log.New(log.Writer(), "[CBR-Demo] ", log.LstdFlags)
	
	// Create CBR configuration
	config := CBRConfig{
		OldN:       4,
		OldF:       1,
		NewN:       6,
		NewF:       2,
		OldIPList:  []string{"127.0.0.1", "127.0.0.1", "127.0.0.1", "127.0.0.1"},
		OldPortList: []string{"11000", "11001", "11002", "11003"},
		NewIPList:  []string{"127.0.0.1", "127.0.0.1", "127.0.0.1", "127.0.0.1", "127.0.0.1", "127.0.0.1"},
		NewPortList: []string{"11000", "11001", "11002", "11003", "11004", "11005"},
		Timeout:    30 * time.Second,
		Retries:    3,
	}
	
	// Create CBR protocol
	cbr := NewCBRProtocol(config, logger)
	
	fmt.Printf("CBR Protocol created with config: OldN=%d, NewN=%d\n", config.OldN, config.NewN)
	
	// Simulate CBR execution
	fmt.Println("Simulating CBR protocol execution...")
	
	// Check initial state
	fmt.Printf("Initial state: %v\n", cbr.GetState())
	
	// Simulate protocol phases
	phases := []struct {
		name  string
		state CBRState
		delay time.Duration
	}{
		{"Prepare", CBRStatePrepare, 100 * time.Millisecond},
		{"ShareReduce", CBRStateShareReduce, 200 * time.Millisecond},
		{"Proactivize", CBRStateProactivize, 150 * time.Millisecond},
		{"ShareDist", CBRStateShareDist, 100 * time.Millisecond},
		{"Complete", CBRStateComplete, 50 * time.Millisecond},
	}
	
	for _, phase := range phases {
		fmt.Printf("Executing phase: %s\n", phase.name)
		cbr.SetState(phase.state)
		time.Sleep(phase.delay)
		fmt.Printf("Phase %s completed, state: %v\n", phase.name, cbr.GetState())
	}
	
	fmt.Println("CBR protocol simulation completed successfully!")
}

// DemoEbbFlowIntegration demonstrates EbbFlow CBR integration
func DemoEbbFlowIntegration() {
	fmt.Println("\n=== EbbFlow CBR Integration Demo ===")
	
	// Create logger
	logger := log.New(log.Writer(), "[EbbFlow-CBR] ", log.LstdFlags)
	
	// Create EbbFlow CBR configuration
	config := EbbFlowCBRConfig{
		NodeID:                 0,
		TotalNodes:            6,
		FaultyNodes:           2,
		ReconfigurationInterval: 10,
		NetworkConfig: NetworkConfig{
			BaseIP:   "127.0.0.1",
			BasePort: 11000,
			IPList:   []string{"127.0.0.1", "127.0.0.1", "127.0.0.1", "127.0.0.1", "127.0.0.1", "127.0.0.1"},
			PortList: []string{"11000", "11001", "11002", "11003", "11004", "11005"},
		},
		EnableMetrics: true,
		MetricsPath:   "./cbr_metrics.json",
	}
	
	// Create EbbFlow CBR integration
	integration := NewEbbFlowCBRIntegration(config, logger)
	
	fmt.Printf("EbbFlow CBR integration created for %d nodes\n", config.TotalNodes)
	
	// Simulate membership changes
	fmt.Println("Simulating membership changes...")
	
	// Test epoch 10 (should trigger reconfiguration)
	epoch := 10
	joinRequests := []string{"127.0.0.1:11006", "127.0.0.1:11007"}
	leaveRequests := []string{"127.0.0.1:11000"}
	
	fmt.Printf("Epoch %d: +%d join, -%d leave\n", epoch, len(joinRequests), len(leaveRequests))
	
	// Check if reconfiguration should be executed
	shouldReconfig := integration.ShouldExecuteCBR(epoch)
	fmt.Printf("Should execute CBR at epoch %d: %v\n", epoch, shouldReconfig)
	
	if shouldReconfig {
		// Calculate new membership
		newMembership := integration.calculateNewMembership(joinRequests, leaveRequests)
		fmt.Printf("New membership size: %d\n", len(newMembership))
		
		// Simulate reconfiguration
		fmt.Println("Simulating reconfiguration...")
		time.Sleep(500 * time.Millisecond)
		
		// Update integration state
		integration.currentEpoch = epoch
		integration.membership = newMembership
		integration.threshold = config.FaultyNodes + 1
		
		fmt.Println("Reconfiguration completed successfully!")
	}
	
	// Display current state
	fmt.Printf("Current epoch: %d\n", integration.GetCurrentEpoch())
	fmt.Printf("Current membership size: %d\n", len(integration.GetCurrentMembership()))
	fmt.Printf("Current threshold: %d\n", integration.GetCurrentThreshold())
	
	// Display metrics
	metrics := integration.GetCBRMetrics()
	fmt.Printf("CBR Metrics: Epoch=%d, Membership=%d, Threshold=%d\n", 
		metrics.CurrentEpoch, metrics.MembershipSize, metrics.Threshold)
	
	fmt.Println("EbbFlow CBR integration demo completed successfully!")
}

// RunCBRDemo runs the complete CBR demo
func RunCBRDemo() {
	fmt.Println("Starting CBR Protocol Demonstration")
	fmt.Println("=====================================")
	
	// Run CBR protocol demo
	DemoCBR()
	
	// Run EbbFlow integration demo
	DemoEbbFlowIntegration()
	
	fmt.Println("\nCBR Protocol Demonstration Completed Successfully!")
}
